package com.pi.wms.service;


import com.pi.common.CodesConstants;
import com.pi.common.utils.StringUtils;
import com.pi.framework.core.repository.IBaseRepository;
import com.pi.framework.core.repository.specification.SimpleSpecificationBuilder;
import com.pi.framework.core.service.impl.BaseCrudService;
import com.pi.framework.core.util.DateUtils;
import com.pi.pro.xcmg.am.common.XcmgAmConstants;
import com.pi.wms.common.WmsConstants;
import com.pi.wms.entity.*;
import com.pi.wms.repository.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;


@Slf4j
@Transactional
@Service
public class CustDyncdataQueryService extends BaseCrudService<TwaDocSoHeader, Long>{

	@Autowired
	protected SoDocumentRepository repository;

	@Autowired
	private StorageListRepository storageListRepository;

    @Autowired
    private AsnRepository asnRepository;

    @Autowired
    private SoRepository soRepository;

    @Autowired
    private CoRepository coRepository;

    @Autowired
    private InventoryDetailsRepository inventoryRepository;

    @Autowired
    private TaskRepository taskRepository;

    @Autowired
    private TransRepository transRepository;

    @Autowired
    private EdiTransactionRepository ediTransactionRepository;

    @Override
	protected IBaseRepository<TwaDocSoHeader,Long> getRepository() {
		return this.repository;
	}

	public List<TwaDocSoHeader> xwmsSoHeaderOf(String groupNo){
        List<TwaDocSoHeader> headers = null;
        if (StringUtils.isNullOrBlank(groupNo)){
            return headers;
        }
        headers=this.repository.findHeadrByDeliveryterms(groupNo);
        return headers;
	}

    public List<TwaDocSoDetails> xwmsSoTaskOf(String taskNumber){
        List<TwaDocSoDetails> lines = null;
        if (StringUtils.isNullOrBlank(taskNumber)){
            return lines;
        }
        lines=this.repository.findDetailsByDeliveryMode(taskNumber.trim());
        return lines;
    }

    /**
     *  清除历史数据
     */
	public String cleanAll(Long divisionId){
        String m = "";
        /**
        if (divisionId==null){
            divisionId= XcmgAmConstants.DIVISION_WH101_ID;
        }
        int count=0;
        try{
            count=this.repository.clean(divisionId);
        }catch (Exception e){
            m="清除历史数据异常.异常:"+e.getMessage();
            e.printStackTrace();
        }
         **/
        return m;
    }

    //
    public List<VwaInventoryStorageList> matchInventory(Long divisionId, TwaDocWaveHeader header, TwaDocWaveDetails details){
        List<VwaInventoryStorageList> storages=null;
        if (details==null){
            return storages;
        }

        SimpleSpecificationBuilder<VwaInventoryStorageList> sb = new SimpleSpecificationBuilder<VwaInventoryStorageList>();
        if (divisionId!=null){
            sb.and("divisionId", "=", divisionId);
        }
        sb.and("materialId", "=", details.getMaterialId());
        String lotval="";

        //WAS批次
        lotval=details.getLotattr05();
        if (!StringUtils.isNullOrBlank(lotval)) {
            sb.and("lotattr05", "=", lotval.trim());
        }
        //通配
        lotval=details.getLotattr06();
        if ((!StringUtils.isNullOrBlank(lotval))
                && (!CodesConstants.COMMON_FLAG_NO.equalsIgnoreCase(XcmgAmConstants.SHIP_RULE_WAVE_ALLOCATOR_MATCH_SUPPLIER))){
            sb.and("lotattr06", "=", lotval.trim());
        }
        //精确
        lotval= CodesConstants.COMMON_WILDCARD;
        if (!StringUtils.isNullOrBlank(details.getLotattr07())) {
            lotval=details.getLotattr07().trim();
        }
        //TODO:HU/202505
        //临时关闭WBS匹配
        sb.and("lotattr07", "=", lotval.trim());

        String worksource=header.getCategory();
        if (!StringUtils.isNullOrBlank(details.getCheckReserveStatus())){
            worksource=details.getCheckReserveStatus();
        }
        if (!StringUtils.isNullOrBlank(worksource)) {
            sb.and("reserveCode", "=", worksource.trim());
        }

        if (!StringUtils.isNullOrBlank(details.getCheckContainNumber())){
            sb.and("containNumber", "=", details.getCheckContainNumber().trim());
        }

        if (!StringUtils.isNullOrBlank(details.getCheckTraceNumber())){
            sb.and("traceNumber", "=", details.getCheckTraceNumber().trim());
        }

        //sb.and("status", "not in ", "('0880','0850')");
        sb.and("status", "=", WmsConstants.STORAGE_STATUS_STORAGE);
        Specification<VwaInventoryStorageList> spec = sb.generateSpecification();
        storages = this.storageListRepository.findAll(spec, Sort.by("lotattr05","pkSeqCode"));//
        return storages;
    }

    public List<TwaDocAsnHeader> queryAsnHeader(Long divisionId, String containerNumber){
        List<TwaDocAsnHeader> headers=null;
        if (StringUtils.isNullOrBlank(containerNumber)){
            return headers;
        }
        containerNumber=containerNumber.trim();
        SimpleSpecificationBuilder<TwaDocAsnHeader> sb = new SimpleSpecificationBuilder<TwaDocAsnHeader>();
        if (divisionId!=null){
            sb.and("divisionId", "=", divisionId);
        }
        sb.and("deliveryContainerNum", "=", containerNumber);
        sb.and("status", "=", WmsConstants.ASN_STATUS_CREATE);
        Specification<TwaDocAsnHeader> spec = sb.generateSpecification();
        headers = this.asnRepository.findAll(spec, Sort.by("id"));//
        return headers;
    }

    public List<TwaDocAsnHeader> queryWorkingAsnHeader(Long divisionId, String containerNumber){
        List<TwaDocAsnHeader> headers=null;
        if (StringUtils.isNullOrBlank(containerNumber)){
            return headers;
        }
        containerNumber=containerNumber.trim();
        SimpleSpecificationBuilder<TwaDocAsnHeader> sb = new SimpleSpecificationBuilder<TwaDocAsnHeader>();
        if (divisionId!=null){
            sb.and("divisionId", "=", divisionId);
        }
        sb.and("deliveryContainerNum", "=", containerNumber);
        sb.and("status", "!=", WmsConstants.ASN_STATUS_CLOSE);
        sb.and("status", "!=", WmsConstants.ASN_STATUS_CANCELL);
        Specification<TwaDocAsnHeader> spec = sb.generateSpecification();
        headers = this.asnRepository.findAll(spec, Sort.by("id"));//
        return headers;
    }

    public List<TwaDocSoHeader> openLastSoDocument(Long divisionId, String category){
        List<TwaDocSoHeader> headers=null;
        if (divisionId==null){
            divisionId=XcmgAmConstants.DIVISION_WH101_ID;
        }
        if (StringUtils.isNullOrBlank(category)){
            category=XcmgAmConstants.WORK_SOURCE_PO;
        }
        SimpleSpecificationBuilder<TwaDocSoHeader> sb = new SimpleSpecificationBuilder<TwaDocSoHeader>();
        if (divisionId!=null){
            sb.and("divisionId", "=", divisionId);
        }
        sb.and("category", "=", category.trim());
        sb.and("status", "!=", WmsConstants.SO_STATUS_CLOSE);
        sb.and("status", "!=", WmsConstants.SO_STATUS_CANCELL);
        Specification<TwaDocSoHeader> spec = sb.generateSpecification();
        headers = this.soRepository.findAll(spec, Sort.by("id").descending());//
        return headers;
    }

    public List<TwaDocCoHeader> openLastCoDocument(Long divisionId, String doctype){
        List<TwaDocCoHeader> headers=null;
        if (divisionId==null){
            divisionId=XcmgAmConstants.DIVISION_WH101_ID;
        }
        if (StringUtils.isNullOrBlank(doctype)){
            doctype=XcmgAmConstants.WORK_SOURCE_PO;
        }
        SimpleSpecificationBuilder<TwaDocCoHeader> sb = new SimpleSpecificationBuilder<TwaDocCoHeader>();
        if (divisionId!=null){
            sb.and("divisionId", "=", divisionId);
        }
        sb.and("type", "=", doctype.trim());
        sb.and("status", "!=", WmsConstants.SO_STATUS_CLOSE);
        sb.and("status", "!=", WmsConstants.SO_STATUS_CANCELL);
        Specification<TwaDocCoHeader> spec = sb.generateSpecification();
        headers = this.coRepository.findAll(spec, Sort.by("id").descending());//
        return headers;
    }

    public List<TwaInventoryDetails> queryInventory(Long divisionId, Long materialId, String fromContainerNumber, String toContainerNumber, Date fromDate, Date toDate){
        List<TwaInventoryDetails> storages=null;
        SimpleSpecificationBuilder<TwaInventoryDetails> sb = new SimpleSpecificationBuilder<TwaInventoryDetails>();
        if (divisionId!=null){
            sb.and("divisionId", "=", divisionId);
        }
        if (materialId!=null){
            sb.and("materialId", "=", materialId);
        }

        if (!StringUtils.isNullOrBlank(fromContainerNumber)){
            sb.and("containNumber", ">=", fromContainerNumber.trim());
        }
        if (!StringUtils.isNullOrBlank(toContainerNumber)){
            sb.and("containNumber", "<=", toContainerNumber.trim());
        }

        if (fromDate!=null){
            //sb.and("receiveTime", ">=", DateUtils.format(fromDate,DateUtils.FORMAT_DATE_YYYY_MM_DD_HH_MM_SS));
            sb.and("receiveTime", ">=", fromDate);
        }
        if (toDate!=null){
            //sb.and("receiveTime", "<=", DateUtils.format(toDate,DateUtils.FORMAT_DATE_YYYY_MM_DD_HH_MM_SS));
            sb.and("receiveTime", "<=", toDate);
        }

        //sb.and("qty", ">", BigDecimal.ZERO);
        Specification<TwaInventoryDetails> spec = sb.generateSpecification();
        List<TwaInventoryDetails> storagesall = this.inventoryRepository.findAll(spec, Sort.by("id"));//
        if ((storagesall==null)||(storagesall.size()==0)){
            return storages;
        }

        storages=new ArrayList<>();
        for (TwaInventoryDetails d:storagesall){
            if (d==null){
                continue;
            }
            if ((d.getQty()==null) || (d.getQty().compareTo(BigDecimal.ZERO))<=0){
                continue;
            }
            storages.add(d);
        }
        return storages;
    }





    public List<TwtActTransList> queryTransByAllocation(Long allocationId){
        List<TwtActTransList> trans=null;
        if (allocationId==null){
            return trans;
        }
        SimpleSpecificationBuilder<TwtActTransList> sb = new SimpleSpecificationBuilder<TwtActTransList>();
        sb.and("refTaskId", "=", allocationId);
        Specification<TwtActTransList> spec = sb.generateSpecification();
        trans = this.transRepository.findAll(spec, Sort.by("id"));//
        return trans;
    }

    public List<TwiActTransList> queryEdiTransByTransId(Long transId){
        List<TwiActTransList> ediTrans=null;
        if (transId==null){
            return ediTrans;
        }
        SimpleSpecificationBuilder<TwiActTransList> sb = new SimpleSpecificationBuilder<TwiActTransList>();
        sb.and("refid", "=", "'"+transId+"'");
        Specification<TwiActTransList> spec = sb.generateSpecification();
        ediTrans = this.ediTransactionRepository.findAll(spec, Sort.by("id"));//
        return ediTrans;
    }
    public List<TwtActTransList> queryTransByBatchnumber(String batchnumber){
        List<TwtActTransList> trans=null;
        if (StringUtils.isNullOrBlank(batchnumber)){
            return trans;
        }
        SimpleSpecificationBuilder<TwtActTransList> sb = new SimpleSpecificationBuilder<TwtActTransList>();
        sb.and("batchNumber", "=", batchnumber.trim());
        Specification<TwtActTransList> spec = sb.generateSpecification();
        trans = this.transRepository.findAll(spec, Sort.by("id"));//
        return trans;
    }

    public List<TwtActTaskList> queryDailyTask(Long divisionId, Date date) {
        List<TwtActTaskList> tasks = null;
        SimpleSpecificationBuilder<TwtActTaskList> sb = null;
        if (date==null){
            date = new Date();
        }
        if (divisionId==null){
            divisionId=XcmgAmConstants.DIVISION_WH101_ID;
        }
        try {
            sb = new SimpleSpecificationBuilder<TwtActTaskList>();
            if (divisionId != null) {
                sb.and("divisionId", "=", divisionId);
            }
            sb.and("createdDate", ">=", DateUtils.tryParse(DateUtils.format(new Date(), DateUtils.FORMAT_DATE_YYYY_MM_DD + " 00:00:00")));
            sb.and("createdDate", "<=", DateUtils.tryParse(DateUtils.format(new Date(), DateUtils.FORMAT_DATE_YYYY_MM_DD + " 23:59:59")));

            //sb.and("status", "!=", WmsConstants.SO_STATUS_CANCELL);
            Specification<TwtActTaskList> spec = sb.generateSpecification();
            tasks = this.taskRepository.findAll(spec, Sort.by("createdDate"));//
        } catch (Exception e) {
            e.printStackTrace();
        }
        return tasks;
    }

    public List<TwaInventoryDetails> queryInventoryByContainers(Long divisionId, Collection<String> containers) {
        List<TwaInventoryDetails> storages = null;
        SimpleSpecificationBuilder<TwaInventoryDetails> sb = null;
        if ((containers==null)||(containers.size()==0)){
            return storages;
        }
        if (divisionId==null){
            divisionId=XcmgAmConstants.DIVISION_WH101_ID;
        }
        try {
            sb = new SimpleSpecificationBuilder<TwaInventoryDetails>();
            if (divisionId != null) {
                sb.and("divisionId", "=", divisionId);
            }
            sb.and("qty", ">", BigDecimal.ZERO);
            sb.and("containNumber", "in", containers);

            //sb.and("status", "!=", WmsConstants.SO_STATUS_CANCELL);
            Specification<TwaInventoryDetails> spec = sb.generateSpecification();
            storages = this.inventoryRepository.findAll(spec, Sort.by("createdDate"));//
        } catch (Exception e) {
            e.printStackTrace();
        }
        return storages;
    }
}
